package org.dxy.middleware.dynamic.thread.pool.infrastructure.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dxy.middleware.dynamic.thread.pool.application.command.commandhandler.RegisterThreadPoolCommandHandler;
import org.dxy.middleware.dynamic.thread.pool.application.view.ThreadPoolView;
import org.dxy.middleware.dynamic.thread.pool.domain.command.RegisterThreadPoolCommand;
import org.dxy.middleware.dynamic.thread.pool.infrastructure.adapter.DynamicThreadPoolService;
import org.dxy.middleware.dynamic.thread.pool.infrastructure.adapter.ThreadPoolQueryRepository;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @ description: 动态配置入口
 * @ author: dxy
 * @ createTime: 2025/9/25 23:49
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class DynamicThreadPoolAutoConfig {
    private final RegisterThreadPoolCommandHandler registerThreadPoolCommandHandler;
    private final ApplicationContext applicationContext;
    private final ThreadPoolQueryRepository threadPoolQueryRepository;



    @Bean
    public DynamicThreadPoolService dynamicThreadPoolService() {
        String appNameTmp = applicationContext.getEnvironment().getProperty("spring.application.name");
        if (StringUtils.isBlank(appNameTmp)) {
            appNameTmp = "未配置";
            log.warn("动态线程池，启动提示。springBoot 应用未配置 spring.application.name， 无法获取应用名称！");
        }
        final String appName = appNameTmp;

        Map<String, ThreadPoolExecutor> threadPoolExecutorMap = applicationContext.getBeansOfType(ThreadPoolExecutor.class);

        log.info("动态线程池初始化，发现 {} 个 ThreadPoolExecutor 实例。", threadPoolExecutorMap.size());

        threadPoolExecutorMap.forEach((threadPoolName, executor) -> {
            log.info("开始注册线程池 -> 名称: {}, 核心线程数: {}, 最大线程数: {}, 队列容量: {}",
                    threadPoolName,
                    executor.getCorePoolSize(),
                    executor.getMaximumPoolSize(),
                    executor.getQueue().remainingCapacity() + executor.getQueue().size()
            );

            // 注册线程池命令
            RegisterThreadPoolCommand command = RegisterThreadPoolCommand.builder()
                    .appName(appName)
                    .threadPoolName(threadPoolName)
                    .corePoolSize(executor.getCorePoolSize())
                    .maximumPoolSize(executor.getMaximumPoolSize())
                    .queueCapacity(executor.getQueue().remainingCapacity() + executor.getQueue().size())
                    .queueType(executor.getQueue().getClass().getSimpleName())
                    .keepAliveTimeValue(executor.getKeepAliveTime(TimeUnit.MILLISECONDS))
                    .keepAliveTimeUnit(TimeUnit.MILLISECONDS)
                    .allowCoreThreadTimeOut(executor.allowsCoreThreadTimeOut())
                    .build();

            registerThreadPoolCommandHandler.handle(command);
            log.info("线程池 {} 注册完成。", threadPoolName);

            // 构造读模型
            ThreadPoolView view = ThreadPoolView.builder()
                    .appName(appName)
                    .threadPoolName(threadPoolName)
                    .corePoolSize(executor.getCorePoolSize())
                    .maximumPoolSize(executor.getMaximumPoolSize())
                    .queueCapacity(executor.getQueue().remainingCapacity() + executor.getQueue().size())
                    .queueType(executor.getQueue().getClass().getSimpleName())
                    .keepAliveTimeValue(executor.getKeepAliveTime(TimeUnit.MILLISECONDS))
                    .keepAliveTimeUnit(TimeUnit.MILLISECONDS)
                    .allowCoreThreadTimeOut(executor.allowsCoreThreadTimeOut())
                    .activeCount(executor.getActiveCount())
                    .poolSize(executor.getPoolSize())
                    .largestPoolSize(executor.getLargestPoolSize())
                    .completedTaskCount(executor.getCompletedTaskCount())
                    .taskCount(executor.getTaskCount())
                    .queueSize(executor.getQueue().size())
                    .remainingCapacity(executor.getQueue().remainingCapacity())
//                    .createTime(LocalDateTime.now()) // 可根据实际创建时间替换
//                    .lastUpdateTime(LocalDateTime.now())
                    .build();


            // 存储到读模型存储，比如 Redis、数据库或内存缓存
            threadPoolQueryRepository.save(view);
        });


        log.info("动态线程池初始化完成，共注册 {} 个线程池。", threadPoolExecutorMap.size());
        return new DynamicThreadPoolService(appName, threadPoolExecutorMap);
    }



}
